package com.matrix.geo.playmysqlgeo.typehandler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKBReader;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@MappedTypes(Geometry.class)
@MappedJdbcTypes(JdbcType.OTHER)
public class MySQLGeometryTypeHandler extends BaseTypeHandler<Geometry> {
    // 将 MySQL 几何数据类型转换为 JTS Geometry 对象
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Geometry parameter, JdbcType jdbcType) throws SQLException {
        ps.setBytes(i, parameter.toText().getBytes());
    }

    // 将 ResultSet 中的几何数据类型转换为 JTS Geometry 对象
    @Override
    public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException {
        byte[] bytes = rs.getBytes(columnName);
        return convertToGeometry(bytes);
    }

    @Override
    public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        byte[] bytes = rs.getBytes(columnIndex);
        return convertToGeometry(bytes);
    }

    // 将 CallableStatement 中的几何数据类型转换为 JTS Geometry 对象
    @Override
    public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        byte[] bytes = cs.getBytes(columnIndex);
        return convertToGeometry(bytes);
    }

    // 将 byte 数组转换为 JTS Geometry 对象
    private Geometry convertToGeometry(byte[] bytes) throws SQLException {
        if (bytes == null) {
            return null;
        }
        WKBReader reader = new WKBReader();
        try {
            return reader.read(bytes);
        } catch (Exception e) {
            throw new SQLException("Failed to convert byte array to JTS Geometry.", e);
        }
    }

}
